<template>
  <ElInput
    placeholder="验证码"
    :modelValue="modelValue"
    class="form-verify-image"
    :style="inputStyle"
    @update:model-value="emit('update:modelValue', $event)"
  >
    <template #suffix>
      <div
        class="form-verify-image-suffix"
        :style="imgStyle"
        :disabled="loading"
        @click="getImage"
      >
        <img class="form-verify-image-suffix-main" :src="imageUrl" alt="" />
      </div>
    </template>
  </ElInput>
</template>
<script lang="ts" setup generic="P extends Record<string, any>">
const props = withDefaults(
  defineProps<{
    modelValue: string;
    imgWidth?: number;
    api: (params?: P) => Promise<string>;
    params?: P;
    /** 是否自动销毁图片链接 */
    autoRevokeUrl?: boolean;
  }>(),
  {
    imgWidth: 100,
  },
);

const emit = defineEmits<(e: "update:modelValue", value: string) => void>();

const loading = ref(false);

const imageUrl = ref("");

const imgMarginLeft = "9px";

const imgStyle = computed(() => {
  return {
    left: `calc(100%  + ${imgMarginLeft})`,
    width: `${props.imgWidth}px`,
  };
});

const inputStyle = computed(() => {
  return {
    width: `calc(100% - ${imgMarginLeft} - ${props.imgWidth}px)`,
  };
});

const getImage = () => {
  if (loading.value) return;
  console.log("获取图片验证码");
  loading.value = true;

  if (imageUrl.value && props.autoRevokeUrl) {
    URL.revokeObjectURL(imageUrl.value);
  }

  props
    .api(props.params)
    .then((url) => {
      imageUrl.value = url;
    })
    .finally(() => {
      loading.value = false;
    });
};

onMounted(() => {
  getImage();
});
</script>
<style lang="less" scoped>
.form-verify-image {
  :deep(.el-input__suffix-inner *) {
    margin: 0;
  }
  &-suffix {
    position: absolute;
    height: 100%;
    border-radius: var(--el-input-border-radius, var(--el-border-radius-base));
    top: 50%;
    transform: translateY(-50%);
    overflow: hidden;
    cursor: pointer;
    &-main {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      background-color: #f4f4f4;
    }
  }
}
</style>
